package com.sgzn.sgpay.dubbo;

import com.alibaba.dubbo.rpc.*;
import com.sgzn.sgpay.model.request.CommonRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 *
 * @author zhongzhongyong
 * @version Id: RemoteServiceFilter.java, v 0.1 2018/4/4 0:23 zhongzhongyong Exp $$
 */
@Slf4j
@Service
public class RemoteServiceFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        //打印交易前日志
        doLogBefore(invoker, invocation);
        Result result = null;
        long startTime = System.currentTimeMillis();
        try {
            //调用真实远程服务
            result = invoker.invoke(invocation);
        } finally {
            //打印交易后日志
            if (result != null && result.getValue() != null) {
                doLogAfter(invoker, result.getValue(), invocation, startTime);
            }
        }
        return result;
    }

    private void doLogBefore(Invoker<?> invoker, Invocation invocation) {
        Object[] arguments = invocation.getArguments();
        String initiationID = this.getInitiationID(arguments);
        log.info("[{}]. Calling remote service [{}-->{}] [{}].Sent request:{}.",
                initiationID, invoker.getInterface().getSimpleName(), invocation.getMethodName(),
                invoker.getUrl().getAddress(), arguments);
    }

    private void doLogAfter(Invoker<?> invoker, Object response, Invocation invocation, long startTime) {
        String initiationID = this.getInitiationID(invocation.getArguments());
        log.info("[{}]. Called remote service [{}-->{}] cost time [{}ms] [{}].Receive response:[{}].",
                initiationID, invoker.getInterface().getSimpleName(), invocation.getMethodName(),
                System.currentTimeMillis() - startTime, invoker.getUrl().getAddress(), response.toString());
    }

    private String getInitiationID(Object[] arguments) {
        if (arguments != null && arguments.length > 0) {
            if (arguments[0] instanceof CommonRequest) {
                return ((CommonRequest) arguments[0]).getInitiationID();
            }
        }
        return "";
    }
}
